<?php
/**
 * This class supports actions for medicine management, ex: list of coefficient, manage medicine
 * usage status ...
 *
 * @package dept_medicine.core.controllers 
 * @author pktquynh
 * @version $Id:$
 * @copyright 2009 LHV Company
 */
$loader->requireOnce('includes/MedicineUsageManagement.class.php');

class C_MedicineManagement extends Controller {
	/* This constant indicates error of existed medicine coefficient when create or edit a medicine coef. */
	const MEDICINE_COEFFICIENT_EXISTED = -1;
	/* This constant is used to name medicine receipt prefix. */
	const MEDICINE_RECEIPT_PREFIX_NAME = "MR_";
	
    var $template_mod;                  
    
    public function C_MedicineManagement($template_mod = "general") {
        parent::Controller();
        $this->template_mod = $template_mod;
        $this->view->path = 'medicine_management';
    }

    /**
     * Action to open the view for managing medicine.
     */
    public function actionMedicineCoefManagement() {
        return $this->view->render('medicine_coef_management.html');
    }
    
    /**
     * List of medicine coefficient.
     * @return Html view 
     */
    public function actionListMedicineCoef() {
        $departments = Celini::newORDO('Department')->getDepartmentList();
        $medTypes = Celini::newORDO('EquipmentType')->getMedicineTypeList();
        
        $this->assign('departments',  $departments);
        $this->assign('medTypes',  $medTypes);
        return $this->view->render('medicine_coefficient_list.html');
    }
    
    /**
     * Search medicine coefficient by department and medicine type.
     * @return list of medicine coefficient in html response
     */
    public function actionSearchMedicineCoef() {
    	$deptId = $_GET['deptId'];
    	$medTypeId = $_GET['medTypeId'];
    	$medCoefs = Celini::newORDO('MedicineCoefficient')->getMedicineCoefs($deptId, $medTypeId);
    	$response = '';
    	foreach ($medCoefs as $medCoef) {
    		$response = $response . $this->buildMedCoefTableResponse($medCoef);
    	}
    	return $response;
    }
    
    private function buildMedCoefTableResponse($medCoef) {
    	$medCoefId = $medCoef['med_coef_id'];
    	$response = '';
    	$response = $response
    	          . "<tr id='" . $medCoefId . "'>"
    	          .     "<td>" . $medCoef['department_name'] . "</td>"
    	          .     "<td>" . $medCoef['medicine_type'] . "</td>"
    	          .     "<td><a href=\"javascript:editMedCoef($medCoefId)\" title='" . L10nHelper::_("Edit") . "'>" . $medCoef['medicine_name'] . "</a></td>"
    	          .     "<td>"
    	          .         "<input type='text' id='medCoef_" . $medCoefId . "_quantity_num' value='" . $medCoef['quantity_num'] . "'>"
    	          .         "&nbsp;" . $medCoef['quantity_title']
    	          .     "</td>"
    	          .     "<td>"
    	          .         "<span id='medCoef_". $medCoefId . "_save'><a href=\"javascript:saveMedCoefQuick($medCoefId)\" title='" . L10nHelper::_("Save") . "'>" . L10nHelper::_("Save") . "</a></span>"
                  .         "<span id='medCoef_" . $medCoefId . "_barLoading' style='display:none;'><img src=\"../images/ajax-loader.gif\"/></span>"
    	          .     "</td>"
                  .     "<td>"
                  .         "<span id='medCoef_".$medCoefId."_remove'>";
        if ($medCoef['deleted'] == 0) {
            $response .=        "<a href=\"javascript:removeMedCoef($medCoefId)\" title='" . L10nHelper::_("Delete") . "'>"
                      .             "<img src=\"../images/lock_small.png\" alt=\"" . L10nHelper::_("Delete") . "\"></img>"
                      .         "</a>";
        } else if ($medCoef['deleted'] == 1) {
            $response .=        "<a href=\"javascript:undoMedCoef($medCoefId)\" title='" . L10nHelper::_("Reuse") . "'>"
                      .             "<img src=\"../images/unlock_small.png\" alt=\"" . L10nHelper::_("Reuse") . "\"></img>"  
                      .         "</a>";
        }
    	$response .=        "</span>"
    	          .     "</td>" 
    	          . "</tr>";
    	return $response;
    }
    
    /**
     * Create or edit one medicine coefficient.
     * @return html view to create/edit medicine coef.
     */
    public function actionEditMedicineCoef() {
    	$medCoefId = '';
    	if (array_key_exists('medCoefId', $_GET)) {
    		$medCoefId = $_GET['medCoefId'];
    	}
        // load the medicine coefficient to edit
        if (isSet($medCoefId) && $medCoefId != "") {
            $medCoef = Celini::newORDO('MedicineCoefficient')->getMedicineCoef($medCoefId);            
            if (!$medCoef || $medCoef['deleted'] == 1) {
                // object not found
                return L10nHelper::_("Medicine coef. not found");
            } else {
                // build data of medicine name select box with the corresonding medicine type            
                $medicines = Celini::newORDO('Medicine')->getMedicineListByType($medCoef['medicine_type_id']);
                $medNameRes = '';           
                foreach ($medicines as $med) {
                    if ($med['medicine_id'] == $medCoef['medicine_id']) {
                       $medNameRes = $medNameRes . $this->buildMedicineSelectResponse($med, "yes");
                    } else {
                        $medNameRes = $medNameRes . $this->buildMedicineSelectResponse($med, "no");
                    }
                }
                $this->assign('medNamesHtml', $medNameRes); 
            }	        
        } else {
        // create mode
        	$medCoef = array('med_coef_id'      => '', 
        	                 'department_id'    => '', 
        	                 'medicine_type_id' => '',
        	                 'medicine_id'      => '',
        	                 'quantity_num'     => '',
        	                 'quantity_title'   => '');
        }
        $this->assign("medCoef", $medCoef);
        $departments = Celini::newORDO('Department')->getDepartmentList();
        $medTypes = Celini::newORDO('EquipmentType')->getMedicineTypeList();
        $this->assign('departments',  $departments);
        $this->assign('medTypes',  $medTypes);
        return $this->view->render('edit_medicine_coef.html');
    }

    /**
     * Get list of medicine names by medicine type.
     * @return list of medicine names in html response
     */
    public function actionGetMedicineNameByTypeAjax() {
    	$medTypeId = $_GET['medTypeId'];
    	if ($medTypeId == 'empty') {
    		return '';
    	}
    	$medicines = Celini::newORDO('Medicine')->getMedicineListByType($medTypeId);
    	$medNameRes = '';
    	foreach ($medicines as $med) {
    		$medNameRes = $medNameRes . $this->buildMedicineSelectResponse($med, "no");
    	}
    	return $medNameRes;
    }
    
    private function buildMedicineSelectResponse($medicine, $selected) {
    	$response = '';
    	if ($selected == 'no') {
    	    $response = "<option id='".$medicine['medicine_id']."' name='".$medicine['name']."' value='".$medicine['medicine_id']."'>".$medicine['name']."</option>";
    	} else {
    	   	$response = "<option selected id='".$medicine['medicine_id']."' name='".$medicine['name']."' value='".$medicine['medicine_id']."'>".$medicine['name']."</option>";
    	}
    	return $response;
    }
    
    /**
     * Save one medicine coefficient.
     * @return the id of medicine coefficient
     */
    public function actionSaveMedicineCoefAjax() {
        $medCoef = Celini::newORDO('MedicineCoefficient');
        $medCoefId = $_POST['medCoefId'];
        
        // check medicine coef. existed
        $existed = $medCoef->checkMedicineCoefExisted($_POST['departmentLbx'], $_POST['medicineNameLbx'], $medCoefId);
        if ($existed) {
        	return C_MedicineManagement::MEDICINE_COEFFICIENT_EXISTED;
        }
        if (isset($medCoefId) && $medCoefId != "") {
            $medCoef->setup($medCoefId);
        }
        $data = array (
            'department_id' => $_POST['departmentLbx'],
            'medicine_id'   => $_POST['medicineNameLbx'],
            'quantity_num'  => $_POST['quantityNumTxt']);
        $medCoef->populateArray($data);
        $medCoef->persist();

        return $medCoef->get_id();
    }
    
    /**
     * Get quantity title of a specific medicine.
     * @return name of quantity title. If not found, return empty string 
     */
    public function actionGetQuantityTitleOfMedicine() {
        $medId = $_GET['medicineId'];
        if ($medId == 'empty') {
        	return '';
        }
        $result = Celini::newORDO('Medicine')->getQuantityTitleOfMedicine($medId);
        if (!$result) {
        	return '';
        } else {
        	return $result['name'];
        }
    }
    
    /**
     * Save medicine coefficient to change quantity number only.
     */
    public function actionSaveMedicineCoefQuickly() {
    	$medCoef = Celini::newORDO('MedicineCoefficient');
    	$medCoef->setup($_GET['medCoefId']);
    	
    	$data = array ('quantity_num'  => $_GET['quantityNum']);
        $medCoef->populateArray($data);
        $medCoef->persist();
    }
    
    /**
     * Remove or undo a specific medicine coefficient.
     * @return the id of medicine coefficient
     */
    public function actionRemoveOrUndoMedicineCoef() {
    	$medCoef = Celini::newORDO('MedicineCoefficient');
        $medCoef->removeOrUndoMedicineCoef($_GET['medCoefId'], $_GET['activity']);
        return $_GET['medCoefId'];
    }
    
    /**
     * Action to open the view for managing medicine usage status.
     */
    public function actionMedicineUsageStatus() {
    	$deptId = $this->_me->get_department_id();
        $deptName = Celini::newORDO('Department', $deptId)->getLocalizedText('name');
        $medTypes = Celini::newORDO('EquipmentType')->getMedicineTypeList();
        
    	$this->assign('deptId', $deptId);
    	$this->assign('deptName', $deptName);
        $this->assign('medTypes',  $medTypes);    	
    	return $this->view->render('medicine_usage_status.html');
    }
    
    /**
     * Search medicine usage status.
     * @return list of medicine usage status in html response
     */
    public function actionSearchMedicineUsgStatus() {
    	$deptId = $this->_me->get_department_id();    	
    	$medTypeId = $_GET['medicineTypeId'];
    	$medId = $_GET['medicineId']; 
    	
        $medUsgMng = new MedicineUsageManagement();
        $medUsgList = $medUsgMng->listLastMedicineUsageForDept($deptId, $medTypeId, $medId);
        
        // format latest date of medicine usage status
        $index = 0;
        foreach ($medUsgList as $medUsg) {
        	if (!isset($medUsg['medicine_usage_status_id'])) {
        		$medUsg['medicine_usage_status_id'] = '';
        		$medUsg['issue_num'] = 0;
        		$medUsg['used_num'] = 0;
        		$medUsg['remain_num'] = 0;
        		$medUsg['latest_date'] = L10nHelper::renderDateTime(date("Y-m-d"), 'short');
        	} else {        		
        		$medUsg['latest_date'] = L10nHelper::renderDateTime($medUsg['latest_date'], 'short');
        	}
        	$medUsgList[$index] = $medUsg;
        	$index++;
        }
        // build html response
        $response = '';
        foreach ($medUsgList as $medUsg) {
        	$response = $response . $this->buildMedUsgStatusTableResponse($medUsg);
        }
        return $response;
    }
    
    private function buildMedUsgStatusTableResponse($medUsg) {
    	$medCoefId = $medUsg['med_coef_id'];
        $medUsgStatusId = $medUsg['medicine_usage_status_id'];

        $response = '';
        $response = $response
                  . "<tr>"
                  .     "<td>" . $medUsg['medicine_type'] . "</td>"
                  .     "<td><a href=\"javascript:updateMedUsageStatus('$medCoefId', '$medUsgStatusId')\" title='" . L10nHelper::_("Update medicine usage status") . "'>" . $medUsg['medicine_name'] . "</a></td>"
                  .     "<td>" . $medUsg['quantity_title'] . "</td>"
                  .     "<td>" . $medUsg['issue_num']  . "</td>"
                  .     "<td>" . $medUsg['used_num']  . "</td>"
                  .     "<td>" . $medUsg['remain_num']  . "</td>"
                  .     "<td>" . $medUsg['latest_date']  . "</td>"
                  . "</tr>";
        
        return $response;   	
    }
    
    /**
     * Update medicine usage status.
     */
    public function actionUpdateMedUsageStatus() {
    	$medCoefId = $_GET['medCoefId'];
    	$medUsgStatusId = $_GET['medUsgStatusId'];
    	
    	$medCoef = Celini::newORDO('MedicineCoefficient')->getMedicineCoef($medCoefId);
    	$medTypeName = Celini::newORDO('EquipmentType', $medCoef['medicine_type_id'])->getLocalizedText('name');
    	$medName = Celini::newORDO('Medicine', $medCoef['medicine_id'])->getLocalizedText('name');
    	
    	$this->assign('medCoefId', $medCoefId); 
    	$this->assign('medTypeName', $medTypeName);
    	$this->assign('medName', $medName);
    	$this->assign('today', L10nHelper::renderDateTime(date("Y-m-d"), 'short'));
    	
    	$medUsgStatusArr = '';
    	/* create mode : 2 case
    	 * 1. This medicine is not existed in 'medicine_usage_status'
    	 * 2. The lastest date of medicine usage status < today (it means create new recored for
    	 * medicine usage status)
    	 */
    	if (isset($medUsgStatusId) && $medUsgStatusId != '') {
    		$medUsgStatus = Celini::newORDO('MedicineUsageStatus', $medUsgStatusId);
    		$lastDate = strtotime($medUsgStatus->get('modified'));
    		$today = strtotime(date("Y-m-d"));
    		if ($lastDate < $today) {
    			// create mode
    			$medUsgStatusArr = array('med_usg_status_id' => '',
                                         'issue_num'         => 0,
                                         'used_num'          => 0,
                                         'remain_num'        => $medUsgStatus->get('remain_num'));
    		} else {
    			// edit mode
    	        $medUsgStatusArr = array('med_usg_status_id' => $medUsgStatusId,
                                         'issue_num'         => $medUsgStatus->get('issue_num'),
                                         'used_num'          => $medUsgStatus->get('used_num'),
                                         'remain_num'        => $medUsgStatus->get('remain_num'));
    		}
    	} else {
    		// create mode
    		$medUsgStatusArr = array('med_usg_status_id' => '',
    		                         'issue_num'         => 0,
    		                         'used_num'          => 0,
    		                         'remain_num'        => 0);
    	}
    	$this->assign('medUsgStatus', $medUsgStatusArr);
    	return $this->view->render('update_med_usage_status.html');
    }
    
    /**
     * Create or update medicine usage status.
     */
    public function actionSaveMedUsageStatusAjax() {
    	$medUsgStatus = Celini::newORDO('MedicineUsageStatus');
        $medUsgStatusId = $_POST['medUsgStatusId'];
        
        if (isset($medUsgStatusId) && $medUsgStatusId != "") {
            $medUsgStatus->setup($medUsgStatusId);
        }
        $data = array (
            'medicine_coefficient_id' => $_POST['medCoefId'],
            'issue_num'               => $_POST['issueNumberTxt'],
            'used_num'                => $_POST['usedNumberTxt'],
            'remain_num'              => $_POST['remainNumberTxt'],
            'modified'                => date("Y-m-d H:i:s"));
        $medUsgStatus->populateArray($data);
        $medUsgStatus->persist();

        return $medUsgStatus->get_id();
    }
    
    /**
     * Action to open view to diplay and print medicine receipt.
     * @return unknown_type
     */
    public function actionMedicineUsageReceipt() {
    	$medTypes = Celini::newORDO('EquipmentType')->getMedicineTypeList();
    	$this->assign('medTypes', $medTypes);
    	return $this->view->render('print_medicine_receipt.html');
    }
    
    /**
     * List medicine receipt. 
     */
    public function actionListMedicineReceipt() {
    	$monthYear = $_GET['month_year'];
    	$deptId = $this->_me->get_department_id();
    	
    	$response = "";
    	if (isset($monthYear) && strpos($monthYear, "/")) {
    		$monYrArr = explode("/", $monthYear);
    		$month = (int)$monYrArr[0];
    		$year = (int)$monYrArr[1];
    		$medReceipts = Celini::newORDO('MedicineUsageReceipt')->listMedicineReceiptInPeriod($deptId, $month, $year);
    		foreach ($medReceipts as $medRec) {
    			$response = $response . $this->buildMedReceiptSelectResponse($medRec);
    		}
    	}
    	return $response;
    }
    
    private function buildMedReceiptSelectResponse($medReceipt) {
    	$response = "<option id='".$medReceipt['id']."' name='".$medReceipt['name']."' value='".$medReceipt['id']."'>".$medReceipt['name']."</option>";
    	return $response;
    }
    
    /**
     * Get medicine receipt by name or by the current medicine usage status in a department.
     * @return array of medicine receipt detail in html response
     */
    public function actionGetMedicineReceipt() {
    	$deptId = $this->_me->get_department_id();
    	$receiptId = $_GET['receiptId'];
    	$medTypeId = $_GET['medTypeId'];
    	
    	$medReceiptDetail = array();
    	if ($receiptId != 'empty') {
    		// search by medicine receipt
    		$medReceiptDetail = Celini::newORDO('MedicineUsageReceipt')->getMedUsageReceipt($receiptId);
    	} else {
    		// search by the current medicine usage status
    		$medReceiptDetail = Celini::newORDO('MedicineUsageStatus')->listLatestMedUsageStatus($deptId, $medTypeId);
    	}
    	$response = "";
    	$idList = array();
    	$index = 0;
    	foreach ($medReceiptDetail as $detail) {
            $response = $response . $this->buildMedReceiptDetailTableResponse($detail, $index);
            array_push($idList, $index);
            $index++;
    	}
    	if ($receiptId != 'empty') {
    	    $response = $response."<input type='hidden' id='medicine_receipt_id' value='".$receiptId."'>";
    	} else {
    		$response = $response."<input type='hidden' id='medicine_receipt_id' value=''>";
    	}
    	$response = $response."<input type='hidden' id='row_id_list' value='".implode(';',$idList)."'>";
    	return $response;
    }
    
    private function buildMedReceiptDetailTableResponse($detail, $index) {
    	$res = "<tr>"
    	     .     "<input type='hidden' id='" . $index."_med_receipt_detail_id"."' name='" . $index."_med_receipt_detail_id"."' value='" . $detail['id'] . "'>"
    	     .     "<td>" . $detail['medicine_type'] . "</td>"
    	     .     "<td>" 
    	     .         $detail['medicine_name']
    	     .         "<input type='hidden' id='" . $index."_medicine_name' name='" . $index."_medicine_name' value='" . $detail['medicine_name'] . "'>" 
    	     .         "<input type='hidden' id='" . $index."_medicine_id' name='" . $index."_medicine_id' value='" . $detail['medicine_id'] . "'>"
    	     .     "</td>"
    	     .     "<td>" 
    	     .         $detail['quantity_title']
             .         "<input type='hidden' id='" . $index."_quantity_title' name='" . $index."_quantity_title' value='" . $detail['quantity_title'] . "'>"    	      
    	     .     "</td>"
    	     .     "<td>" 
    	     .         $detail['used_num'] 
    	     .         "<input type='hidden' id='" . $index."_used_num' name='" . $index."_used_num' value='" . $detail['used_num'] . "'>"
    	     .     "</td>"
    	     .     "<td>" 
    	     .         $detail['remain_num']
    	     .         "<input type='hidden' id='" . $index."_remain_num' name='" . $index."_remain_num' value='" . $detail['remain_num'] . "'"
    	     .             "onkeyup=\"javascript:this.value=this.value.replace(/[^0-9]/g, '');\">" 
    	     .     "</td>"
    	     .     "<td>"
    	     .         "<input type='text' id='" . $index."_requirement_num' name='" . $index."_requirement_num' value='" . $detail['requirement_num'] . "'>"
    	     .     "</td>"
    	     . "</tr>";
    	return $res;
    }
    
    /**
     * Add or update medicine usage receipt and its receipt detail.
     * @return the id of created/updated medicine usage receipt
     */
    public function actionAddOrUpdateMedReceipt() {
        $medReceiptId = $_POST['medReceiptId'];
        $rowIds = split(";", $_POST['rowIds']);
        $recDetailData = $this->processSerializedForm($_POST['receiptDetailForm']);
        if (empty($rowIds)) {
        	return -1;
        }
        // save medicine receipt
        $medReceipt = Celini::newORDO('MedicineUsageReceipt');
        $data = "";
        if (isset($medReceiptId) && $medReceiptId != "") {
        	// update mode
        	$medReceipt->setup($medReceiptId);
            $data = array('modified' => date("Y-m-d H:i:s"));
        } else {
        	// create mode
        	$data = array('department_id' => $this->_me->get_department_id(),
        	              'name'          => C_MedicineManagement::MEDICINE_RECEIPT_PREFIX_NAME . L10nHelper::renderDateTime(date("Y-m-d"), 'short'),
        	              'modified'      => date("Y-m-d H:i:s"));
        }
        $medReceipt->populateArray($data);
        $medReceipt->persist();
        
        // save medicine receipt detail
        foreach ($rowIds as $i) {
        	$recDetailId = $recDetailData[$i.'_med_receipt_detail_id'];
        	$recDetail = Celini::newORDO('MedicineUsageReceiptDetail');
        	if (isset($recDetailId) && $recDetailId != "") {
        		// update mode
        		$recDetail->setup($recDetailId);
        		$data = array('requirement_num' => $recDetailData[$i.'_requirement_num']);
        	} else {
        		// create mode
        		$data = array('medicine_usage_receipt_id' => $medReceipt->get_id(),
        		              'medicine_id'               => $recDetailData[$i.'_medicine_id'],
        		              'used_num'                  => $recDetailData[$i.'_used_num'],
        		              'remain_num'                => $recDetailData[$i.'_remain_num'],
        		              'requirement_num'           => $recDetailData[$i.'_requirement_num']);
        	}        	
        	$recDetail->populateArray($data);
        	$recDetail->persist();
        }
        return $medReceipt->get_id();
    }
    
    private function processSerializedForm($serialized){
        $post = explode('&',$serialized);
        $keys = array();
        $vals = array();
        foreach ($post as $item){
            $item = explode('=', $item);
            array_push($keys, $item[0]);
            array_push($vals,$item[1]);
        }
        return array_combine($keys,$vals);
    }
    
    /**
     * Print one medicine receipt with its detail (medicine name, quantity title, require number ...)
     * @return printed content in html view
     */
    public function actionPrintMedicineReceipt() {
        $medReceiptId = $_GET['medReceiptId'];
        $medReceiptDetail = Celini::newORDO('MedicineUsageReceipt')->getMedUsageReceipt($medReceiptId);
        
        $printedRowList = array();
        $index = 0;
        foreach ($medReceiptDetail as $detail) {
            $item = array('index'           => $index,
                          'medicine_name'   => $detail['medicine_name'],
                          'quantity_title'  => $detail['quantity_title'],
                          'requirement_num' => $detail['requirement_num']);
            array_push($printedRowList, $item);
            $index++;
        }
        
        $hospitalInfo = Celini::configInstance()->get('hospital_info');
        $hosInfoLocale = $hospitalInfo[L10nHelper::getLocale()];
        $deptId = $this->_me->get_department_id();
        $deptName = Celini::newORDO('Department', $deptId)->getLocalizedText('name');
        
        $this->assign('hospitalManage', $hosInfoLocale['manage_department']);
        $this->assign('hospitalName', $hosInfoLocale['name']);
        $this->assign('deptName', $deptName);
        $this->assign('printedRowList', $printedRowList);
        return $this->view->render('print_medicine_receipt_detail.html');
    }
}
?>